﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;



namespace LDAPOfficeTool
{
    public partial class LDAPTaskPane : UserControl
    {

        // LDAP Service variables / constants
        LDAPServiceNS.OrganisationBean[] MainOrganisationArr;
        LDAPServiceNS.OrganisationBean[] MainOrganisationUnsortedArr;
        Person2DisplayUniversal[] Person2DisplayUniversalAr;
        bool Initialized = true;  // if it was possible to initialize the addin
        Org2DisplayUniversal[] Org2DisplayUniversalAr;
        string EndpointName = "?";
        string PersonErrorMsg;
        const int MaxPersonsLimit = 200;
        const int MaxOrgsLimit = 100;
        const string NotInitializedMsg = "LDAP Service wurde nicht korrekt initialisiert-FEHLER";
        const string SearchCriteriaMissingMsg = "Geben Sie zumindest ein Suchkriterium ein!";
        const string NothingFoundMsg = "Kein Eintrag gefunden, der die Suchkriterien erfüllt!";
        const string HelpText = @"
<html>
<head>
<meta http-equiv=Content-Type content='text/html; charset=windows-1252'>
<meta name=Generator content='Microsoft Word 14 (filtered)'>
<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:10.0pt;
	margin-left:0cm;
	line-height:115%;
	font-size:11.0pt;
	font-family:'Calibri','sans-serif';}
a:link, span.MsoHyperlink
	{color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;}
.MsoChpDefault
	{font-family:'Calibri','sans-serif';}
.MsoPapDefault
	{margin-bottom:10.0pt;
	line-height:115%;}
@page WordSection1
	{size:595.3pt 841.9pt;
	margin:70.85pt 354.3pt 2.0cm 70.85pt;}
div.WordSection1
	{page:WordSection1;}
-->
</style>
</head>
<body lang=DE-AT link=blue vlink=purple>
<div class=WordSection1>
<p class=MsoNormal><b>Hilfe zum Add-In LDAP.gv.at</b></p>
<p class=MsoNormal>Im Behördenverzeichnis LDAP.gv.at finden Sie
Kontaktinformationen der Mitarbeiter und Mitarbeiterinnen von 
Institutionen der österreichischen Verwaltung.</p>
<p class=MsoNormal><i>Suche nach Personen: </i></p>
<p class=MsoNormal>Sie können nach Nachnamen, Telefonnummern oder Aufgaben
suchen. Wählen Sie eine Organisation aus, wenn Sie Ihre Suche z.B. auf ein
Ministerium einschränken wollen. </p>
<p class=MsoNormal>Als Ergebnis erhalten Sie eine Liste mit den Namen und
E-Mail-Adressen der gefundenen Personen. Der Name ist mit einem Link versehen,
wenn Sie darauf klicken, erhalten Sie eine Webansicht mit allen verfügbaren
Informationen zur Person. </p>
<p class=MsoNormal>Durch Klick auf das Pfeilsymbol erhalten Sie weitere Infos.
Mit dem Button <i>Einfügen</i> können Sie Elemente (wie z.B. Namen oder
Anschrift) in ihr geöffnetes Worddokument übernehmen. </p>
<p class=MsoNormal><i>Suche nach Organisationen:</i> </p>
<p class=MsoNormal>Hier finden Sie Informationen zu den Organisationseinheiten
(z.B. Sektionen oder Abteilungen). Als Suchfelder stehen Ihnen Bezeichnung,
Kurzbezeichnung und Aufgabe zur Verfügung. </p>
<p class=MsoNormal>Wie bei der Personensuche erhalten Sie eine Trefferliste,
die einen Link zur Webansicht enthält. Nach Klick auf das Pfeilsymbol können
Sie Daten (wie z.B. Anschrift oder Bezeichnung der Organisationseinheit) in ihr
aktives Dokument übernehmen. </p>
<p class=MsoNormal><a
href='http://www.help.gv.at/ldapw/index.php?useDesign=help' target='_blank'>
Webanwendung Behördenverzeichnis…</a> </p>
<p class=MsoNormal>© LFRZ GmbH 2011</p>
</div>
</body>
</html>";


        public LDAPTaskPane()
        {

            string HelpPath;
            InitializeComponent();
            InitializeLDAP();
            lblHitCountO.Text = "";
            lblHitCountP.Text = "";
            HelpPath = "file://" + Environment.CurrentDirectory + "\\" + "HelpForLdap.htm";
            webBrowserHelp.DocumentText = HelpText;
        }


        private void InitializeLDAP()
        {
            // initialize the main combobox to be able to switch between organizations         
            LDAPServiceNS.LdapGvAtQueryClient ldapServiceInit;
            try
            {
                ldapServiceInit = new LDAPServiceNS.LdapGvAtQueryClient();
                EndpointName = ldapServiceInit.Endpoint.Address.ToString();
                // BBB09 old call with 9 parameter is switched off
//                tMainOrganisationUnsorted = ldapServiceInit.findOrganizationsBy(null, null, null, null, null, null, true, null, 20);
                MainOrganisationUnsortedArr = ldapServiceInit.findOrganizationsBy(null, null, null, null, null, null, null, true, true, 20);

                ldapServiceInit.Close();
                cmbBxOrgOrg.Items.Add("ALLE");
                cmbBxPersOrg.Items.Add("ALLE");
                // now, take care about sorting
                SortedList<string, int> MainOrganisationsSorted;
                MainOrganisationsSorted = new SortedList<string, int>(MainOrganisationUnsortedArr.Length);
                for (int i =0; i < MainOrganisationUnsortedArr.Length; i++)
                {
                    MainOrganisationsSorted.Add(MainOrganisationUnsortedArr[i].ou, i);
                }
                // now, sort tMainOrganisation physically, because for the rest of the program
                MainOrganisationArr = new LDAPServiceNS.OrganisationBean[MainOrganisationUnsortedArr.Length];
                for (int i = 0; i < MainOrganisationArr.Length; i++)
                {
                    MainOrganisationArr [i] = MainOrganisationUnsortedArr[MainOrganisationsSorted.Values[i]];
                }

                for (int i = 0; i < MainOrganisationArr.Length; i++)
                {
                    cmbBxOrgOrg.Items.Add(MainOrganisationArr[i].ou);
                    cmbBxPersOrg.Items.Add(MainOrganisationArr[i].ou);
                }
            }
            catch (Exception ex1)
            {
                // make it uninitialized again
                MessageBox.Show("LDAP Service kann nicht initialisiert werden: " + ex1.Message);
                Initialized = false;
            }
            cmbBxPersOrg.SelectedIndex = 0;
            cmbBxOrgOrg.SelectedIndex = 0;
        }


        private void btnPSearch_Click(object sender, EventArgs e)
        {
            PersonSearch();
        }


        bool PSearchAllowed()
        {
            bool RetVal;
            RetVal = true;
            int DataLength;
            if (!Initialized)
            {
                MessageBox.Show(NotInitializedMsg);
                RetVal = false;
            }
            else
            {
                DataLength = txtBxPAufgb.Text.Length + txtBxPName.Text.Length + txtBxPTel.Text.Length;
                if (DataLength < 1)
                {
                    MessageBox.Show(SearchCriteriaMissingMsg);
                    RetVal = false;
                }
            }
            return RetVal;
        }


        void PersonSearch()
        {
            int ColorCntr;
            Color CurrentColor;
            ColorCntr = 0;
            string Name2Search;
            string Phone2Search;
            string Aufgabe;
            if (PSearchAllowed())
            {

                LDAPServiceNS.LdapGvAtQueryClient ldapService;
                ldapService = new LDAPServiceNS.LdapGvAtQueryClient();
                LDAPServiceNS.PersonBean[] PersonArr;
                string GvOuId;
                PersonErrorMsg = "";
                // we must differ if the selected is 0 (ALLE) or something
                if (cmbBxPersOrg.SelectedIndex > 0)
                {
                    GvOuId = MainOrganisationArr[cmbBxPersOrg.SelectedIndex - 1].gvOuId;
                }
                else
                {
                    GvOuId = null;
                }

                if (txtBxPName.Text.Length > 0)
                {
                    Name2Search = txtBxPName.Text + "*";
                }
                else
                {
                    Name2Search = null;
                }

                if (txtBxPTel.Text.Length > 0)
                {
                    Phone2Search = "*" + (txtBxPTel.Text + "*");
                }
                else
                {
                    Phone2Search = null;
                }

                if (txtBxPAufgb.Text.Length > 0)
                {
                    Aufgabe = "*" + txtBxPAufgb.Text + "*";
                }
                else
                {
                    Aufgabe = null;
                }
                try
                {
                    PersonArr = ldapService.findPersonsByDetail(null, null, Name2Search, null, Phone2Search, Aufgabe, Aufgabe, null, GvOuId, MaxPersonsLimit);
                    ldapService.Close();
                    flowLayoutPanelP.Controls.Clear();
                    if (PersonArr != null)
                    {
                        if (PersonArr.Length >= MaxPersonsLimit)
                        {
                            MessageBox.Show("Abfrage liefert mehr Ergebnisse als erlaubt (" + MaxPersonsLimit.ToString() + ")");
                        }

                        Person2DisplayUniversalAr = new Person2DisplayUniversal[PersonArr.Length];
                        lblHitCountP.Text = "Treffer: " + PersonArr.Length.ToString();

                        for (int i = 0; i < PersonArr.Length; i++)
                        {
                            /// REMOVE
                            if ((PersonArr[i].gvOu.Length > 1))
                            {
                                PersonErrorMsg = PersonErrorMsg + PersonArr[i].givenName + " " + PersonArr[i].sn + "  multiple orgs: " + PersonArr[i].gvOu.Length.ToString() + Environment.NewLine;
                            }
                            if (ColorCntr == 0)
                            {
                                CurrentColor = Color.Aquamarine;
                                ColorCntr = 1;
                            }
                            else
                            {
                                CurrentColor = Color.LightGreen;
                                ColorCntr = 0;
                            }

                            // determine person's main organisation
                            int AuxCounter1; // auxilliary counter to go through the whole array
                            bool MainOrgUnknown;
                            AuxCounter1 = 0;
                            MainOrgUnknown = true;
                            string PersonMainOrg;
                            string PersonMainOrgKurzBez;
                            PersonMainOrg = " ? ";
                            PersonMainOrgKurzBez = " ? ";
                            while (MainOrgUnknown && AuxCounter1 < MainOrganisationArr.Length)
                            {
                                if (PersonArr[i].gvOrganisationGvOuId == MainOrganisationArr[AuxCounter1].gvOuId)
                                {
                                    MainOrgUnknown = false;
                                    PersonMainOrg = MainOrganisationArr[AuxCounter1].cn[0];
                                    PersonMainOrgKurzBez = MainOrganisationArr[AuxCounter1].ou;
                                }
                                AuxCounter1++;
                            }

                            // once we sent here the main org, now we send main org Kurzbezeichnung
                            Person2DisplayUniversalAr[i] = new Person2DisplayUniversal(PersonArr[i], PersonMainOrg, PersonMainOrgKurzBez, Globals.ThisAddIn.Application.ActiveDocument);
                            flowLayoutPanelP.Controls.Add(Person2DisplayUniversalAr[i]);
                        }
                        TextBox TextBoxForErrors; // to inform about loading errors;
                        // check if the error button is to be displayed
                        if (PersonErrorMsg.Length > 0)
                        {
                            TextBoxForErrors = new TextBox();
                            TextBoxForErrors.Text = PersonErrorMsg;
                            TextBoxForErrors.Visible = true;
                            TextBoxForErrors.ReadOnly = true;
                            TextBoxForErrors.Multiline = true;
                            TextBoxForErrors.Width = Person2DisplayUniversalAr[0].Width;
                            TextBoxForErrors.Height = 150;
                            TextBoxForErrors.BackColor = Color.LightPink;
                            flowLayoutPanelP.Controls.Add(TextBoxForErrors);
                        }
                    }
                    else
                    {
                        MessageBox.Show(NothingFoundMsg);
                        lblHitCountP.Text = "0";
                    }
                }
                catch (Exception ex1)
                {
                    MessageBox.Show("Exception at findPersonsByDetail: " + ex1.Message);
                }
            }
         }


        private void btnOSearch_Click(object sender, EventArgs e)
        {
            OrgSearch();
        }



        bool OSearchAllowed()
        {
            bool RetVal;
            RetVal = true;
            int DataLengthTotalSum;
            if (!Initialized)
            {
                MessageBox.Show(NotInitializedMsg);
                RetVal = false;
            }
            else
            {
                DataLengthTotalSum = txtBxOBez.Text.Length + txtBxOKurzB.Text.Length + txtBxOAufgb.Text.Length;
                if (DataLengthTotalSum < 1)
                {
                    MessageBox.Show(SearchCriteriaMissingMsg);
                    RetVal = false;
                }
            }
            return RetVal;
        }



        private void OrgSearch()
        {
            string SearchBez;
            string SearchKurzBez;
            string SearchAufgbOrg;
            string GvOuId;
            bool Inserted; // help flag to check if the entry was processed in loop
            int InsertingId;

            // check if the search will be allowed at all:
            if (OSearchAllowed())
            {
                LDAPServiceNS.LdapGvAtQueryClient ldapService;
                ldapService = new LDAPServiceNS.LdapGvAtQueryClient();
                LDAPServiceNS.OrganisationBean[] OrgArr;
                if (cmbBxOrgOrg.SelectedIndex > 0)
                {
                    GvOuId = MainOrganisationArr[cmbBxOrgOrg.SelectedIndex - 1].gvOuId;
                }
                else
                {
                    GvOuId = null;
                }
                SearchBez = "*" + txtBxOBez.Text + "*";
                SearchKurzBez = txtBxOKurzB.Text;
                SearchAufgbOrg = "*" + txtBxOAufgb.Text + "*";
                try
                {
                    // BBB09 change from 9 parameters
//                    tOrg = ldapService.findOrganizationsBy(sgvouid, null, sSearchBez, sSearchKurzBez, sSearchAufgbOrg, null, false, true, ciMaxOrgs);
                    // BBB09, this is 2. change, test of OR-parameter usage
//                    tOrg = ldapService.findOrganizationsBy(sgvouid, null, sSearchBez, sSearchKurzBez, sSearchAufgbOrg, null, null, false, true, ciMaxOrgs);
                    OrgArr =  ldapService.findOrganizationsBy (GvOuId, null, SearchBez, SearchBez, SearchKurzBez, SearchAufgbOrg, SearchAufgbOrg, false, true, MaxOrgsLimit);
                    ldapService.Close();
                    flowLayoutPanelO.Controls.Clear();
                    if (OrgArr != null)
                    {
                        Org2DisplayUniversalAr = new Org2DisplayUniversal[OrgArr.Length];
                        if (OrgArr.Length >= MaxOrgsLimit)
                        {
                            MessageBox.Show("Abfrage liefert mehr Ergebnisse als erlaubt (" + MaxOrgsLimit.ToString() + ")");
                        }
                        // now, make sorted lookup structure
                        SortedList<string, int> OrgSortedStruct;
                        OrgSortedStruct = new SortedList<string, int>(OrgArr.Length);
                        for (int i = 0; i < OrgArr.Length; i++)
                        {
                            Inserted = false;
                            InsertingId = 0;
                            while (!Inserted)
                            {
                                try
                                {
                                    //  MessageBox.Show("Data: cn[0]: " + tOrg[i].cn[0] + " gvCn: " + tOrg[i].gvCn + " gvoucn: " + tOrg[i].gvOuCn + "  : " + tOrg[i].gvOrganisationGvOuId + "  gvouvkz: " + tOrg[i].gvOuVKZ);
                                    // BBB09 - extending key to sort because of ambiguity
                                    //                                OrgSortedStruct.Add(tOrg[i].cn[0], i);
                                    OrgSortedStruct.Add(OrgArr[i].cn[0] + OrgArr[i].gvOrganisationGvOuId + InsertingId.ToString (), i);
                                    Inserted = true;
                                }
                                catch (Exception ex)
                                {
//                                    MessageBox.Show("Key already exists, error at idx: " + i.ToString() + Environment.NewLine + "at: " + tOrg[i].cn[0] + ";/;" + tOrg[i].gvOrganisationGvOuId + Environment.NewLine + "trynr: " + iInsertingId.ToString() + Environment.NewLine + "Exception: " + ex.Message);
                                    InsertingId++;
                                }
                            }
                        }
                        lblHitCountO.Text = "Treffer: " + OrgArr.Length.ToString();
                        // go through SORTED list now
                        int IndexActive;  // help variable to connect the sorted list and the rest of data
                        for (int i = 0; i < OrgArr.Length; i++)
                        {
                            IndexActive = OrgSortedStruct.Values[i];
                            int AuxCounter1;
                            bool MainOrgUnknown;  // to determine if the main org of the item can be determined
                            AuxCounter1 = 0;
                            MainOrgUnknown = true;
//                            string sMainOrg;
                            string MainOrgKurzBez;
// BBB09 we do not use smainorg; good ?
//                            sMainOrg = " ? ";
                            MainOrgKurzBez = " ? ";
                            while (MainOrgUnknown && AuxCounter1 < MainOrganisationArr.Length)
                            {
                                if (OrgArr[IndexActive].gvOrganisationGvOuId == MainOrganisationArr[AuxCounter1].gvOuId)
                                {
                                    MainOrgUnknown = false;
// BBB09 we remove the line from program, if it makes problems ?
//                                    sMainOrg = tMainOrganisation[iAux1].cn[0];
                                    MainOrgKurzBez = MainOrganisationArr[AuxCounter1].ou;
                                }
                                AuxCounter1++;
                            }
                            Org2DisplayUniversalAr[i] = new Org2DisplayUniversal(OrgArr[IndexActive], MainOrgKurzBez, Globals.ThisAddIn.Application.ActiveDocument);
                            flowLayoutPanelO.Controls.Add(Org2DisplayUniversalAr[i]);
                            //                tOrg2DisplayUniversal[
                        }
                    }
                    else
                    {
                        MessageBox.Show(NothingFoundMsg);
                        lblHitCountO.Text = "0";
                    }

                }
                catch (Exception ex1)
                {
                    MessageBox.Show("Exception at findOrganizationsBy: " + ex1.Message + "  stack: " + ex1.StackTrace);
                }
            }
        }


        private void btnErrP_Click(object sender, EventArgs e)
        {
            MessageBox.Show(PersonErrorMsg);
        }


        private void txtBxPName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char) Keys.Enter)
            {
                PersonSearch();
            }
        }

        private void txtBxPTel_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                PersonSearch();
            }
        }

        private void txtBxPAufgb_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                PersonSearch();
            }
        }


        private void txtBxOAufgb_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                OrgSearch();
            }
        }

        private void txtBxOKurzB_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                OrgSearch();
            }
        }

        private void txtBxOBez_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                OrgSearch();
            }
        }



        private void lblPName_DoubleClick(object sender, EventArgs e)
        {
            string DiagnosticsTxt;
            DiagnosticsTxt = "LDAP Office Tool diagnostics: " + Environment.NewLine;
            DiagnosticsTxt = DiagnosticsTxt + "Current Directory: " + Environment.CurrentDirectory + Environment.NewLine;
            DiagnosticsTxt = DiagnosticsTxt + "System  Directory: " + Environment.SystemDirectory;
            MessageBox.Show(DiagnosticsTxt);
        }

        private void lblPersOrg_DoubleClick(object sender, EventArgs e)
        {
            string DiagnosticTxt;
            DiagnosticTxt = "v.2011.06.29 18:00" + Environment.NewLine;
            DiagnosticTxt = DiagnosticTxt + "Limits: Persons: " + MaxPersonsLimit.ToString() + "  Orgs: " + MaxOrgsLimit.ToString() + Environment.NewLine;
            DiagnosticTxt = DiagnosticTxt + EndpointName;
            MessageBox.Show(DiagnosticTxt);
        }

    }
}
